﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.Web.Security;
using ExtremeEvents.Models;
using System.IO;

namespace ExtremeEvents.Controllers
{
    [Authorize(Roles = "Utilizador")]
    public class EventoManagerController : Controller
    {
        //
        // GET: /EventoManager/

        public ActionResult Index()
        {
            return View();
        }

        //
        // GET: /EventoManager/NovoEvento
        public ActionResult AddEvento()
        {
            Guid userGuid = (Guid)Membership.GetUser().ProviderUserKey; //Guid do utilizador
            ViewUtilizador utilizador = searchUser(userGuid);            

            List<Categoria> lista_categoria =  getAllCategoria();

            Evento evento = new Evento
            {
                id_utilizador = utilizador.guid,
                categorias = lista_categoria,
                data_inicio = DateTime.Now,
                data_fim = DateTime.Now
            };
            ViewBag.id_categoria = new SelectList(lista_categoria, "id_categoria", "descricao");
            return View(evento);
        }
        //
        // POST: /EventoManager/NovoEvento
        [HttpPost]
        public ActionResult AddEvento(Evento evento)
        {

            if (ModelState.IsValid)
            {
                //Cria uma ligação com a base de dados
                ExtremeEventsIntity db = new ExtremeEventsIntity();
                // Objeto que vai conter os parametros do evento
                object[] param = new object[15];
                param[0] = evento.id_utilizador;
                param[1] = evento.id_categoria;
                param[2] = evento.data_inicio;
                param[3] = evento.data_fim;
                param[4] = evento.titulo;
                param[5] = evento.descricao;
                param[6] = evento.preco;
                param[7] = evento.morada;
                param[8] = evento.codigo_postal;
                param[9] = evento.url;
                param[10] = evento.contacto_telefonico;
                param[11] = evento.email;
                param[12] = evento.latitude;
                param[13] = evento.longitude;
                param[14] = evento.cancelado;
                //Executar o SP de adicionar um novo evento
                db.Database.ExecuteSqlCommand("EXEC ext.sp_fe_addEvento {0}, {1}, {2}, {3}, {4}, {5}, {6}, {7}, {8}, {9}, {10}, {11}, {12}, {13}, {14}", param);
            }
            else
            {
                ModelState.AddModelError("", "Error_26: verifique se preencheu todos os campos obrigatórios corretamente.");
                ViewBag.id_categoria = new SelectList(getAllCategoria(), "id_categoria", "descricao");
                return View(evento);
            }

            return RedirectToAction("AddEventoSuccess");
        }

        //
        // GET: /EventoManager/AddEventoSucess
        public ActionResult AddEventoSuccess()
        {

            return View();
        }

        //
        // GET: /EventoManager/EventosUtilizador
        public ActionResult EventosUtilizador()
        {
            Guid userGuid = (Guid)Membership.GetUser().ProviderUserKey; //Guid do utilizador

            List<Evento> lista_eventos_utilizador = getEventoByUtilizador(userGuid);
            //Se não existir nenhum evento é redirecionado 
            //para uma página que informa que não existe eventos
            if (lista_eventos_utilizador.Count == 0)
                return RedirectToAction("EventosUtilizadorZeroCount");

            return View(lista_eventos_utilizador);
        }

        //
        // GET: /EventoManager/EventosCategoria
        public ActionResult EventosUtilizadorZeroCount()
        {
            return View();
        }
        
        //
        // GET: /EventoManager/EditarEvento
        public ActionResult EditarEvento(int id)
        {            
            List<Categoria> lista_categoria = getAllCategoria();
            Evento evento = getEventoById(id);

            ViewBag.id_categoria = new SelectList(lista_categoria, "id_categoria", "descricao");
            return View(evento);            
        }

        //
        // POST: /EventoManager/EditarEvento
        [HttpPost]
        public ActionResult EditarEvento(Evento evento)
        {
            if (ModelState.IsValid)
            {
                //Cria uma ligação com a base de dados
                ExtremeEventsIntity db = new ExtremeEventsIntity();
                // Objeto que vai conter os parametros do evento
                object[] param = new object[15];
                param[0] = evento.id_evento;
                param[1] = evento.id_categoria;
                param[2] = evento.data_inicio;
                param[3] = evento.data_fim;
                param[4] = evento.titulo;
                param[5] = evento.descricao;
                param[6] = evento.preco;
                param[7] = evento.morada;
                param[8] = evento.codigo_postal;
                param[9] = evento.url;
                param[10] = evento.contacto_telefonico;
                param[11] = evento.email;
                param[12] = evento.latitude;
                param[13] = evento.longitude;
                param[14] = evento.cancelado;
                //Executar o SP de adicionar um novo evento
                db.Database.ExecuteSqlCommand("EXEC ext.sp_fe_editEvento {0}, {1}, {2}, {3}, {4}, {5}, {6}, {7}, {8}, {9}, {10}, {11}, {12}, {13}, {14}", param);
            }
            else
            {
                ModelState.AddModelError("", "Error_26: verifique se preencheu todos os campos obrigatórios corretamente.");
                ViewBag.id_categoria = new SelectList(getAllCategoria(), "id_categoria", "descricao");
                return View(evento);
            }
            return RedirectToAction("EditEventoSucess");
        }

        //
        // GET: /EventoManager/EditEventoSucess
        public ActionResult EditEventoSucess()
        {

            return View();
        }

        //
        // GET: /EventoManager/CancelarEvento
        public ActionResult CancelarEvento(int id)
        {
            Evento evento = getEventoById(id);
            return View(evento);
        }

        //
        // POST: /EventoManager/CancelarEvento
        [HttpPost]
        public ActionResult CancelarEvento(Evento evento)
        {
            ExtremeEventsIntity db = new ExtremeEventsIntity();
            object[] param = new object[2];  // Objeto que vai conter os parametros do evento
            //Preencher os parametros do evento
            param[0] = evento.id_evento;
            param[1] = true;
            //Executar o SP de alterar estado do evento
            db.Database.ExecuteSqlCommand("EXEC ext.sp_fe_alterarEstadoEvento {0}, {1}", param);

            return RedirectToAction("EventosUtilizador", "EventoManager");
        }

        //
        // GET: /EventoManager/AssociarFoto
        public ActionResult AssociarFoto(int id)
        {
            return View();
        }

        //
        // POST: /EventoManager/AssociarFoto
        [HttpPost]
        public ActionResult AssociarFoto(HttpPostedFileBase file, int id)
        {
            //Se não existe ficheiro, não guarda....
            if (file != null)
            {
                //Prepara uma pasta local temporária
                var path = Path.Combine(Server.MapPath("~/Temp/Foto"), file.FileName);
                //Guarda o ficheiro em pasta temporária
                file.SaveAs(path);
                //Processa a imagem em byte para ser colocada na base de dados
                byte[] bufferImageData = System.IO.File.ReadAllBytes(path);
                //Cria uma ligação com a base de dados
                ExtremeEventsIntity db = new ExtremeEventsIntity();
                // Objeto que vai conter os parametros da foto
                object[] param = new object[3];
                param[0] = id;
                param[1] = bufferImageData;
                param[2] = null;
                //Executar o SP de adicionar uma novo foto
                db.Database.ExecuteSqlCommand("EXEC ext.sp_fe_addFoto {0}, {1}, {2}", param);
                return RedirectToAction("AssociarFotoSuccess");
            }
            return View();
        }
        
        //
        // GET: /EventoManager/AssociarFoto
        public ActionResult AssociarFotoSuccess()
        {

            return View();
        }

        //
        // GET: /EventoManager/AdicionarFlyer
        public ActionResult AdicionarFlyer(int id)
        {
            return View();
        }

        //
        // POST: /EventoManager/AdicionarFlyer
        [HttpPost]
        public ActionResult AdicionarFlyer(HttpPostedFileBase file, int id)
        {
            //Se não existe ficheiro, não guarda....
            if (file != null)
            {
                //Prepara uma pasta local temporária
                var path = Path.Combine(Server.MapPath("~/Temp/Flyer"), file.FileName);
                //Guarda o ficheiro em pasta temporária
                file.SaveAs(path);
                //Processa a imagem em byte para ser colocada na base de dados
                byte[] bufferImageData = System.IO.File.ReadAllBytes(path);
                //Cria uma ligação com a base de dados
                ExtremeEventsIntity db = new ExtremeEventsIntity();
                // Objeto que vai conter os parametros do flyer
                object[] param = new object[3];
                param[0] = id;
                param[1] = bufferImageData;
                param[2] = null;
                //Executar o SP de adicionar um flyer
                db.Database.ExecuteSqlCommand("EXEC ext.sp_fe_addFlyer {0}, {1}, {2}", param);
                return RedirectToAction("AdicionarFlyerSuccess");
            }
            return View();
        }

        //
        // GET: /EventoManager/AdicionarFlyer
        public ActionResult AdicionarFlyerSuccess()
        {

            return View();
        }

        /// <summary>
        /// Métdodo para devolver dados do utilizador autenticado.
        /// </summary>
        /// <param name="userGuid"></param>
        /// <returns>Utilizador</returns>
        public ViewUtilizador searchUser(Guid userGuid)
        {
            ExtremeEventsIntity db = new ExtremeEventsIntity();
            //Executar o store procedure e retornar DbSet do objeto utilizador.
            db.ViewUtilizadores.SqlQuery("EXEC ext.sp_fe_searchUser_ByGuid {0}", userGuid).ToList();
            //criar objeto utilizador com os dados recolhidos da base de dados
            ViewUtilizador utilizador = (ViewUtilizador)db.ViewUtilizadores.Find(userGuid);
            
            return utilizador;
        }

        /// <summary>
        /// Método para devolver todas as categorias do evento
        /// </summary>
        /// <returns>Uma lista do tipo Categoria</returns>
        public List<Categoria> getAllCategoria()
        {
            ExtremeEventsIntity db = new ExtremeEventsIntity();
            return db.categorias.SqlQuery("EXEC ext.sp_fe_listarCategorias").ToList<Categoria>();
        }

        /// <summary>
        /// Obter os eventos apenas do utilizador autenticador
        /// </summary>
        /// <param name="guid"></param>
        /// <returns>Lista de eventos do utilizador</returns>
        public List<Evento> getEventoByUtilizador(Guid guid)
        {
            ExtremeEventsIntity db = new ExtremeEventsIntity();
            return db.eventos.SqlQuery("EXEC ext.sp_fe_listarEventos_porUtilizador {0}", guid).ToList<Evento>();
        }
        /// <summary>
        /// Obter o evento atravez do id
        /// </summary>
        /// <param name="id"></param>
        /// <returns>Um objecto do tipo evento</returns>
        public Evento getEventoById(int id)
        {
            ExtremeEventsIntity db = new ExtremeEventsIntity();
            db.eventos.SqlQuery("EXEC ext.sp_fe_listarEventos_porId {0}", id).ToList<Evento>();
            return db.eventos.Find(id);
        }
    }
}